package edu.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;

import edu.terapia.model.Cita;
import edu.terapia.model.Paciente;
import edu.terapia.model.Persona;
import edu.terapia.model.Servicio;
import edu.util.HbnUtil;

@ManagedBean(name="citaBean")
@SessionScoped
public class CitaBean implements Serializable {

	public Cita cita ;
	public List<Cita> citaList = null;
	
	public List<Paciente> pacientes = null;
	public Paciente paciente = null;
	
	public List<Persona> terapeutas = null;
	public Persona terapeuta = null;
	
	public List<Servicio> servicios = null;
	public Servicio servicio = null;
	
	public static final int TIPO_PERSONA_TERAPEUTA_ID = 100;
	
		
	@SuppressWarnings("unchecked")
	public CitaBean() {
		cita = new Cita();
		paciente = new Paciente();
		terapeuta = new Persona();
		servicio = new Servicio();
		
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		pacientes = getCPacienteList(s);
		citaList  = getC_CitaList(s);
		terapeutas = getCTerapeutas(s);
		//servicios = getCServicios(s);
		servicios = new ArrayList<Servicio>();
		t.commit();
		s.close();
	}

	public String save() {
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		
		cita.setPaciente(paciente);
		cita.setTerapeuta(terapeuta);
		cita.setServicio(servicio);
		List<Cita> ct = hasCitas(s, cita.getFechaCreacion(), terapeuta.getId());
		if(ct.size() > 0) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ya este terapeuta tiene citas en esa fechas",  "Ya este terapeuta tiene citas en esa fechas" );  
		    FacesContext.getCurrentInstance().addMessage(null, msg);
		    return null;
		}
		
		cita.setStatus("creado");
		cita.setHorasFacturadas(1);
		
		s.getCurrentSession().save(cita);
		citaList  = getC_CitaList(s);
		t.commit();
		s.close();
		return "cita?faces-redirect=true";
	}
	
	public String update() {
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		
		cita.setPaciente(paciente);
		cita.setTerapeuta(terapeuta);
		cita.setServicio(servicio);
		
		s.getCurrentSession().update(cita);
		citaList  = getC_CitaList(s);
		t.commit();
		s.close();
		return "cita?faces-redirect=true";
	}
	
	public String edit(Cita cita) {
		this.cita = cita;
		this.paciente = cita.getPaciente();
		this.terapeuta = cita.getTerapeuta();
		this.servicio = cita.getServicio();
		
		return "update_cita?faces-redirect=true";
	}
	
	public String delete(Cita cita) {
		this.cita = cita;
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		s.getCurrentSession().delete(cita);
		citaList  = getC_CitaList(s);
		t.commit();
		s.close();
		return "cita?faces-redirect=true";
	}
	
	public String confirmar(Cita cita) {
		this.cita = cita;
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		confirmar_update(s, cita.getId());
		citaList  = getC_CitaList(s);
		t.commit();
		s.close();
		return "cita?faces-redirect=true";
	}
	
	public void clear() {
		cita = new Cita();
		paciente = new Paciente();
		terapeuta = new Persona();
		servicio = new Servicio();
		
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		pacientes = getCPacienteList(s);
		terapeutas = getCTerapeutas(s);
		//servicios = getCServicios(s);
		servicios = new ArrayList<Servicio>();
		
		t.commit();
		s.close();
	}
	
	@SuppressWarnings("unchecked")
	private List<Paciente> getCPacienteList(SessionFactory s) {
		return s.getCurrentSession()
				.createCriteria(Paciente.class)
				.addOrder(Order.desc("id"))
				.list();
	}
	
	@SuppressWarnings("unchecked")
	private List<Cita> getC_CitaList(SessionFactory s) {
		return 
		s.getCurrentSession()
		.createSQLQuery("select c.* from citas c ")
		.addEntity(Cita.class)
		.list();
	}
	
	@SuppressWarnings("unchecked")
	private List<Persona> getCTerapeutas(SessionFactory s) {
		return 
				s.getCurrentSession()
				.createSQLQuery("select c.* from persona c where c.tipo_persona_id = :tipo ")
				.addEntity(Persona.class)
				.setParameter("tipo", TIPO_PERSONA_TERAPEUTA_ID)
				.list();
	}
	
	@SuppressWarnings("unchecked")
	private List<Servicio> getCServicios(SessionFactory s) {
		return 
				s.getCurrentSession()
				.createSQLQuery("select s.* from servicios s ")
				.addEntity(Servicio.class)
				.list();
	}
	
	@SuppressWarnings("unchecked")
	private List<Servicio> getCServiciosByTerapeuta(SessionFactory s, int terapeutaID) {
		return 
				s.getCurrentSession()
				.createSQLQuery(
						"SELECT s.* FROM servicios s, persona p, personas_servicios ps "
						+ " where ps.personas_id = p.id and ps.servicios_id = s.id  and p.id = :terapeuta")
				.addEntity(Servicio.class)
				.setParameter("terapeuta", terapeutaID)
				.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Cita> hasCitas(SessionFactory s, Date d, int terapeutaID) {
		List<Cita> temp1 =  s.getCurrentSession().createSQLQuery(
				"SELECT c.* FROM citas c "
				+ "where  :fecha "
				+ "between c.FECHA_CREACION and (c.FECHA_CREACION + interval 1 hour) "
				+ "and c.TERAPEUTA_ID = :terapeuta")
		.addEntity(Cita.class)
		.setParameter("fecha", d)
		.setParameter("terapeuta", terapeutaID)
		.list();
		
		if(temp1.size() == 0) {
			temp1 =  s.getCurrentSession().createSQLQuery(
					"SELECT c.* FROM citas c "
					+ "where  (:fecha + interval 1 hour)"
					+ "between c.FECHA_CREACION and (c.FECHA_CREACION + interval 1 hour) "
					+ "and c.TERAPEUTA_ID = :terapeuta")
			.addEntity(Cita.class)
			.setParameter("fecha", d)
			.setParameter("terapeuta", terapeutaID)
			.list();
		}
		
		return temp1;
	}
	
	
	@SuppressWarnings("unused")
	private void confirmar_update(SessionFactory s, int citaID) {
				s.getCurrentSession()
				.createSQLQuery("update citas set status = 'confirmado' where id = :citaID")
				.setParameter("citaID", citaID)
				.executeUpdate();
	}
	
	@SuppressWarnings("unused")
	public void changeTerapeuta(ValueChangeEvent valueChangeEvent) {
		Persona p = (Persona)valueChangeEvent.getNewValue();
		SessionFactory s =  HbnUtil.getSessionFactory();
		Transaction t = s.getCurrentSession().beginTransaction();
		servicios = getCServiciosByTerapeuta(s, p.getId());	
		t.commit();
		s.close();
	}
	

	public Cita getCita() {
		return cita;
	}

	public void setCita(Cita cita) {
		this.cita = cita;
	}

	public List<Cita> getCitaList() {
		return citaList;
	}

	public void setCitaList(List<Cita> citaList) {
		this.citaList = citaList;
	}

	public List<Paciente> getPacientes() {
		return pacientes;
	}

	public void setPacientes(List<Paciente> pacientes) {
		this.pacientes = pacientes;
	}

	public Paciente getPaciente() {
		return paciente;
	}

	public void setPaciente(Paciente paciente) {
		this.paciente = paciente;
	}

	public Persona getTerapeuta() {
		return terapeuta;
	}
	public void setTerapeuta(Persona terapeuta) {
		this.terapeuta = terapeuta;
	}
	
	public List<Persona> getTerapeutas() {
		return terapeutas;
	}
	public void setTerapeutas(List<Persona> terapeutas) {
		this.terapeutas = terapeutas;
	}
	
	public Servicio getServicio() {
		return servicio;
	}
	public List<Servicio> getServicios() {
		return servicios;
	}
	
	public void setServicio(Servicio servicio) {
		this.servicio = servicio;
	}
	public void setServicios(List<Servicio> servicios) {
		this.servicios = servicios;
	}
}
